package com.smzd.framework.config.intercepters;

import java.lang.reflect.Method;

import org.springframework.ui.ExtendedModelMap;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.support.HandlerMethodInvoker;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.servlet.mvc.annotation.IMethodIntercepter;
import org.springframework.web.servlet.mvc.annotation.MethodIntercepterChain;

import com.smzd.framework.annotation.Access;
import com.smzd.framework.utils.JsonHelper;
import com.smzd.framework.utils.Privilege;

public abstract class BaseMethodPrivilegeIntercepter implements
		IMethodIntercepter {

	private String loginPage = "/users/login";
	private String noauthPage = "global/error/401.ftl";
	private String rejectMessage = "您无权访问！";
	private String loginPrompt = "请先登录";
	private String reduceMessage = "您访问当前功能的授权由于所在组织的授权被取消而无法使用。";
	private String reducePage = "global/error/401-1.ftl";

	@Override
	public Object doMethodIntercept(HandlerMethodInvoker invoker,
			Object handler, Method handlerMethod, ServletWebRequest webRequest,
			ExtendedModelMap model, MethodIntercepterChain chain)
			throws Exception {
		int canAccess = 0;
		Privilege privilege = null;
		boolean userLoggedIn = isUserLoggedIn();
		if (userLoggedIn) {
			privilege = getPrivilege();
		}
		if (handlerMethod.isAnnotationPresent(Access.class)) {
			Access access = handlerMethod.getAnnotation(Access.class);
			if (access != null) {
				String[] tags = access.value();
				if (tags != null && tags.length > 0) {
					if (userLoggedIn) {
						canAccess = privilege.hasTag(tags);
					}
				} else {
					canAccess = 1;
				}
			} else {
				canAccess = 1;
			}
		} else // 未标记，则使用全局配置。全局配置存在时，必须用户登录，否则不允许使用该功能
		if (handler.getClass().isAnnotationPresent(Access.class)) {
			Access access = handler.getClass().getAnnotation(Access.class);
			if (userLoggedIn) {
				if (access != null) {
					String[] tags = access.value();
					canAccess = privilege.hasTag(tags);
				} else {
					canAccess = 1;
				}
			}
		} else {// 全局也没有配置，则可以访问
			canAccess = 1;
		}
		Object obj;
		if (canAccess == 1) {// 可以访问，继续走下面的流程
			try {
				obj = chain.doChain(invoker, handler, handlerMethod,
						webRequest, model);
			} catch (Exception e) {
				if (handlerMethod.isAnnotationPresent(ResponseBody.class)) {
					obj = JsonHelper.getFailJsonString(e.getMessage());
				}else{
					throw e;
				}
			}
		} else if (canAccess == -1) {// 有授权，但无法访问。暗示了该流程一定是用户登录了的
			if (handlerMethod.isAnnotationPresent(ResponseBody.class)) {
				obj = JsonHelper.getFailJsonString(reduceMessage);
			} else {
				obj = reducePage;
			}
		} else if (handlerMethod.isAnnotationPresent(ResponseBody.class)) {
			obj = JsonHelper.getFailJsonString(userLoggedIn ? rejectMessage
					: loginPrompt);
		} else if (userLoggedIn) {
			obj = noauthPage;
		} else {
			obj = "redirect:" + loginPage;
		}
		return obj;
	}

	protected abstract Privilege getPrivilege();

	protected abstract boolean isUserLoggedIn();

	public void setLoginPage(String loginPage) {
		this.loginPage = loginPage;
	}

	public void setNoauthPage(String noauthPage) {
		this.noauthPage = noauthPage;
	}

	public void setRejectMessage(String rejectMessage) {
		this.rejectMessage = rejectMessage;
	}

	public void setLoginPrompt(String loginPrompt) {
		this.loginPrompt = loginPrompt;
	}

	public void setReduceMessage(String reduceMessage) {
		this.reduceMessage = reduceMessage;
	}

	public void setReducePage(String reducePage) {
		this.reducePage = reducePage;
	}
}
